import {
  Module,
  OnApplicationBootstrap,
  OnModuleInit,
  OnModuleDestroy,
  BeforeApplicationShutdown,
  OnApplicationShutdown,
  forwardRef,
  DynamicModule,
  NestModule,
  MiddlewareConsumer,
  RequestMethod,
} from '@nestjs/common';
import { ModuleRef } from '@nestjs/core'; // ModuleRef 获取当前模块的引用
import { PersonService } from './person.service';
import { PersonController } from './person.controller';
import { Person2Controller } from './person2.controller';
import { AppModule } from 'src/app.module';
import { AppService } from 'src/app.service';
import { LogMiddleware } from 'src/log.middleware';

@Module({})
// imports: [forwardRef(() => AppModule)], // 模块循环引用
//   controllers: [PersonController],
//   providers: [PersonService],
//   exports: [PersonService],
export class PersonModule
  implements
    OnModuleInit,
    OnApplicationBootstrap,
    OnModuleDestroy,
    BeforeApplicationShutdown,
    OnApplicationShutdown,
    NestModule
{
  constructor(private readonly moduleRef: ModuleRef) {}

  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LogMiddleware)
      .forRoutes({ path: '/api/person/find', method: RequestMethod.GET });
  }
  // 动态生成模块
  static register(options: Record<string, any>): DynamicModule {
    return {
      module: PersonModule,
      // imports: [forwardRef(() => AppModule)], // 模块循环引用
      controllers: [Person2Controller, PersonController],
      providers: [
        PersonService,
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
      ],
      exports: [PersonService],
    };
  }

  static forRootAsync(options: Record<string, any>): DynamicModule {
    return {
      module: PersonModule,
      imports: [forwardRef(() => AppModule)], // 模块循环引用
      controllers: [PersonController],
      providers: [
        PersonService,
        // {
        //   provide: 'CONFIG_OPTIONS',
        //   useFactory: async (optionsFactory: PersonOptionsFactory) =>
        //     await optionsFactory.createPersonOptions(),
        //   inject: [options.useClass],
        // }
      ],
    };
  }
  onModuleInit() {
    console.log('PersonModule onModuleInit~');
  }
  onApplicationBootstrap() {
    console.log('PersonModule onApplicationBootstrap~');
  }

  onModuleDestroy() {
    console.log('PersonModule onModuleDestroy~');
  }
  beforeApplicationShutdown(signal: string) {
    console.log('PersonModule beforeApplicationShutdown~', signal);
  }
  onApplicationShutdown() {
    const personService = this.moduleRef.get<PersonService>(PersonService);
    console.log(personService.create({ age: 18, name: 'person' }));
    console.log('当前模块引用==', this.moduleRef);
    console.log('PersonModule onApplicationShutdown~');
  }
}
